package com.example.parking.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.parking.common.PageRequest;
import com.example.parking.common.Result;
import com.example.parking.dto.ParkingRecordDTO;
import com.example.parking.entity.*;
import com.example.parking.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/parking-record")
public class ParkingRecordController {

    @Autowired
    private ParkingRecordService parkingRecordService;
    @Autowired
    private ParkingLotService parkingLotService;
    @Autowired
    private ParkingSpaceService parkingSpaceService;
    @Autowired
    private VehicleService vehicleService;
    @Autowired
    private UserService userService;

    @PostMapping
    public Result<ParkingRecord> create(@RequestBody ParkingRecord parkingRecord) {
        parkingRecord.setEntryTime(LocalDateTime.now());
        parkingRecord.setStatus(1); // 停车中
        parkingRecordService.save(parkingRecord);
        return Result.success(parkingRecord);
    }

    @PutMapping("/{id}")
    public Result<ParkingRecord> update(@PathVariable Long id, @RequestBody ParkingRecord parkingRecord) {
        ParkingRecord existingRecord = parkingRecordService.getById(id);
        if (existingRecord == null) {
            return Result.error("记录不存在");
        }
        // 复制请求体中的非空属性到现有记录，不包括ID
        BeanUtils.copyProperties(parkingRecord, existingRecord, "id");

        System.out.println("Updating record with spaceId: " + existingRecord.getSpaceId());

        parkingRecordService.updateById(existingRecord);
        return Result.success(existingRecord);
    }

    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable Long id) {
        parkingRecordService.removeById(id);
        return Result.success(null);
    }

    @GetMapping("/{id}")
    public Result<ParkingRecordDTO> getById(@PathVariable Long id) {
        ParkingRecord record = parkingRecordService.getById(id);
        if (record == null) {
            return Result.error("记录不存在");
        }

        ParkingRecordDTO dto = convertToDto(record);
        return Result.success(dto);
    }

    @GetMapping("/page")
    public Result<Page<ParkingRecordDTO>> page(PageRequest pageRequest, ParkingRecord parkingRecord) {
        Page<ParkingRecord> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        LambdaQueryWrapper<ParkingRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(parkingRecord.getLotId() != null, ParkingRecord::getLotId, parkingRecord.getLotId())
                .eq(parkingRecord.getSpaceId() != null, ParkingRecord::getSpaceId, parkingRecord.getSpaceId())
                .eq(parkingRecord.getVehicleId() != null, ParkingRecord::getVehicleId, parkingRecord.getVehicleId())
                .eq(parkingRecord.getUserId() != null, ParkingRecord::getUserId, parkingRecord.getUserId())
                .eq(parkingRecord.getStatus() != null, ParkingRecord::getStatus, parkingRecord.getStatus())
                .orderByDesc(ParkingRecord::getCreateTime);

        Page<ParkingRecord> rawPage = parkingRecordService.page(page, wrapper);

        List<ParkingRecordDTO> dtoList = rawPage.getRecords().stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());

        Page<ParkingRecordDTO> dtoPage = new Page<>(rawPage.getCurrent(), rawPage.getSize(), rawPage.getTotal());
        dtoPage.setRecords(dtoList);

        return Result.success(dtoPage);
    }

    @PostMapping("/{id}/exit")
    public Result<ParkingRecordDTO> exit(@PathVariable Long id) {
        ParkingRecord record = parkingRecordService.getById(id);
        if (record == null) {
            return Result.error("记录不存在");
        }
        if (record.getStatus() != 1) {
            return Result.error("该记录状态不正确");
        }

        LocalDateTime exitTime = LocalDateTime.now();
        record.setExitTime(exitTime);
        record.setStatus(2); // 已离场
        parkingRecordService.updateById(record);

        // 重新获取更新后的记录，并转换为DTO
        ParkingRecord updatedRecord = parkingRecordService.getById(id);
        ParkingRecordDTO dto = convertToDto(updatedRecord);
        return Result.success(dto);
    }

    @PostMapping("/{id}/pay")
    public Result<ParkingRecordDTO> pay(@PathVariable Long id) {
        ParkingRecord record = parkingRecordService.getById(id);
        if (record == null) {
            return Result.error("记录不存在");
        }
        if (record.getStatus() != 2) {
            return Result.error("该记录状态不正确");
        }

        record.setStatus(3); // 已支付
        parkingRecordService.updateById(record);

        // 重新获取更新后的记录，并转换为DTO
        ParkingRecord updatedRecord = parkingRecordService.getById(id);
        ParkingRecordDTO dto = convertToDto(updatedRecord);
        return Result.success(dto);
    }

    private ParkingRecordDTO convertToDto(ParkingRecord record) {
        ParkingRecordDTO dto = new ParkingRecordDTO();
        BeanUtils.copyProperties(record, dto);

        // 计算停车时长和费用
        if (record.getEntryTime() != null && record.getExitTime() != null) {
            long durationMinutes = Duration.between(record.getEntryTime(), record.getExitTime()).toMinutes();
            dto.setDuration((int) durationMinutes);

            ParkingLot parkingLot = parkingLotService.getById(record.getLotId());
            if (parkingLot != null && parkingLot.getHourlyRate() != null) {
                // 计算费用：时长（分钟） / 60 * 每小时费用
                BigDecimal hourlyRate = parkingLot.getHourlyRate();
                BigDecimal durationHours = BigDecimal.valueOf(durationMinutes).divide(BigDecimal.valueOf(60), 2, BigDecimal.ROUND_HALF_UP);
                BigDecimal fee = durationHours.multiply(hourlyRate).setScale(2, BigDecimal.ROUND_HALF_UP);
                dto.setFee(fee);
            }
        }

        // 填充关联名称
        ParkingLot parkingLot = parkingLotService.getById(record.getLotId());
        if (parkingLot != null) {
            dto.setLotName(parkingLot.getName());
        }

        ParkingSpace parkingSpace = parkingSpaceService.getById(record.getSpaceId());
        if (parkingSpace != null) {
            dto.setSpaceNumber(parkingSpace.getSpaceNumber());
        }

        Vehicle vehicle = vehicleService.getById(record.getVehicleId());
        if (vehicle != null) {
            dto.setPlateNumber(vehicle.getPlateNumber());
        }

        User user = userService.getById(record.getUserId());
        if (user != null) {
            dto.setUsername(user.getUsername());
        }

        return dto;
    }
} 